#ifndef VECTOR2D_H_INCLUDED
#define VECTOR2D_H_INCLUDED


#include <cmath> 


struct Vector2D
{
public:
    // The default dtor, copy ctor, copy assignment operator,
    // move ctor, move copy ctor and move assignment operator
    // will be sufficient

    Vector2D() : x(0), y(0) {}

    Vector2D(float x_, float y_)
        : x(x_), y(y_) {}

    // For vector negation
    Vector2D operator-() const { return Vector2D(-x, -y); }

    Vector2D operator+(const Vector2D& vec) const
    {
        return Vector2D(x + vec.x, y + vec.y);
    }

    Vector2D operator-(const Vector2D& vec) const
    {
        return Vector2D(x - vec.x, y - vec.y);
    }

    Vector2D operator*(float val) const
    {
        return Vector2D(x * val, y * val);
    }

    Vector2D operator/(float val) const
    {
        // if a == 0 => ...
        return Vector2D(x * 1.0f / val, y * 1.0f / val);
    }

    Vector2D& operator+=(const Vector2D& vec)
    {
        x += vec.x;
        y += vec.y;

        return *this;
    }

    Vector2D& operator-=(const Vector2D& vec)
    {
        x -= vec.x;
        y -= vec.y;

        return *this;
    }

    Vector2D& operator*=(float val)
    {
        x *= val;
        y *= val;
    }

    Vector2D& operator/=(float val)
    {
        // if a == 0 => ...
        x *= 1.0f / val;
        y *= 1.0f / val;

        return *this;
    }

    void Zero()
    {
        x = y = 0.0f;
    }

    void Normalize()
    {
        float magnitude_sqr = x * x + y * y;

        if (magnitude_sqr > 0.0f)
        {
            x *= 1.0f / sqrt(magnitude_sqr);
            y *= 1.0f / sqrt(magnitude_sqr);
        }
    }

    // Dot product
    float operator*(const Vector2D& vec) const
    {
        return x * vec.x + y * vec.y;
    }

    bool operator==(const Vector2D& vec) const
    {
        return (x == vec.x) && (y == vec.y);
    }

    // Implement operator!= in terms of operator==
    bool operator!=(const Vector2D& vec)
    {
        return !(*this == vec);
    }

    float x;
    float y;
};


float Magnitude(const Vector2D&); 
Vector2D operator*(float, const Vector2D&); 
float Distance(const Vector2D&, const Vector2D&); 


#endif // VECTOR2D_H_INCLUDED
